#ifndef _QUERY_OUTPUT_H_
#define _QUERY_OUTPUT_H_

#if defined(_MSC_VER)  &&  _MSC_VER >= 1310
# pragma warning( disable: 4244 )     // disable lost of data warning
#endif 

#if defined(_MSC_VER)  &&  _MSC_VER >= 1310
# pragma warning( disable: 4996 )     // disable func_s deprecation warning
#endif 

#include <string>
#include <vector>

#include "json/json.h"
#include "Query.h"
#include "Timer.h"

struct QueryPrintStructure
{
	std::pair <std::string, OperatorNode *> name;

	std::vector <QueryPrintStructure *> lists;

	QueryPrintStructure(Query *query);
	~QueryPrintStructure();	
};

class QueryOutput
{
private:
	std::ofstream dot;
	std::ofstream ofile;

	Json::Value root;

	void initialize();

	std::string createCMD(std::string from, std::string to);

	void printQuery(QueryPrintStructure *qps);
	bool printQuery(QueryInfo *qi, std::string dir);	
public:
	QueryOutput();
	~QueryOutput();

	void beginOutput(std::string name);
	void endOutput(std::string name);

	void printOptimizationResults(std::string name, int min_query, double min_cost, double start_cost, uint64_t time);
	void printQuery(QueryInfo *qi, int current);
	void printQuery(Json::Value &node, Query *query);
	bool printQuery(Query *query, std::string filename);
	bool printQueries(QueryStorage *qst, std::string dir, std::string algorithmName);

	inline void visualize(std::string from, std::string to = "");	

	inline QueryOutput& operator << (std::string str);
	inline QueryOutput& operator << (int i);
	inline QueryOutput& operator << (double d);
	inline QueryOutput& operator << (uint64_t ui64);	
};

#endif